'''菜单的相关视图函数'''
import datetime

from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.views import APIView

from common.db_util import MySqlDb
from common.http_util import Result
from  system.system_models import *

'''用户左侧加载的菜单栏'''
def to_menu_bar(request):
    return render(request, "page/system/sys_menu_bar.html")


'''进入菜单页面'''
def to_menu(request):
    print("=========== 请求进入到了menu_tree.html ==========")
    return render(request, 'page/system/sys_menu.html')


'''菜单列表'''
class MenuList(APIView):
    def get(self, request):
        print("=========== 进入到了MenuList ==========")
        # 请求参数
        params = request.GET.dict()
        print("请求参数：", params)
        #根据系统ID查询菜单列表
        sql = "select * from sys_menu sm where sm.status=1 and system_id =:system_id order by sort asc"
        list = MySqlDb.query(sql, params=params)
        #散列成字典
        menu_dict = {}
        for item in list:
            menu_dict[item["id"]] = item
        #组装树形结构
        menu_tree = []
        for item in list:
            #如果父菜单ID为0，说明是根菜单
            if item["parent_id"] == 0:
                menu_tree.append(item)
            else:
                #如果父菜单ID不为0，说明是子菜单
                parent_menu = menu_dict[item["parent_id"]]
                #子菜单不存在时，创建一个空列表
                if "children" not in parent_menu:
                    parent_menu["children"] = []
                #把子菜单添加到父菜单的children列表中
                parent_menu["children"].append(item)
        return Response(Result(data=menu_tree))

'''查询菜单挂载树,新增或修改时调用，查询出菜单的上下级关系'''
class MenuSelectTree(APIView):
    def get(self, request):
        print("=========== 进入到了MenuTree ==========")
        # 请求参数
        params = request.GET.dict()
        print("请求参数：", params)
        #取出系统ID
        system_id = params.get("system_id")
        #查询出所有的菜单
        sql = "select * from sys_menu sm where sm.is_leaf=0 and sm.status=1 and system_id =:system_id order by sort asc"
        list = MySqlDb.query(sql, params=params)
        #散列成字典
        # menu_dict = {}
        # for item in list:
        #     menu_dict[item["id"]] = item
        #组装树形结构
        menu_tree = []
        temp_dict = {}
        for item in list:
            id = item["id"]
            # 组装新的字典
            tree_item = {
                "id": id,
                "label": item["menu_name"],
                #不展开
                "expanded": False,
            }
            #建立关系使用
            temp_dict[id]=tree_item
            #如果父菜单ID为0，说明是根菜单
            if item["parent_id"] == 0:
                menu_tree.append(tree_item)
            else:
                #如果父菜单ID不为0，说明是子菜单
                parent_menu = temp_dict[item["parent_id"]]
                #子菜单不存在时，创建一个空列表
                if "children" not in parent_menu:
                    parent_menu["children"] = []
                #把子菜单添加到父菜单的children列表中
                parent_menu["children"].append(tree_item)

        return Response(Result(data=menu_tree))


'''更新菜单'''
class MenuUpdate(APIView):
    def post(self, request):
        print("=========== 进入到了MenuUpdate ==========")
        session = None
        try:
            # 请求参数
            params = request.data
            print("请求参数：", params)
            id=params.get("id")
            session = MySqlDb.get_mysql_session()
            menu:Menu = session.query(Menu).filter(Menu.id==id).first()
            if menu:
                #字段parent_id,menu_name,path,icon,sort,permission,menu_type,component,visible,cache,system_id,short_name,remark,status
                menu.parent_id = params.get("parent_id")
                menu.menu_name = params.get("menu_name")
                menu.path = params.get("path")
                menu.icon = params.get("icon")
                menu.sort = params.get("sort")
                menu.permission = params.get("permission")
                menu.menu_type = params.get("menu_type")
                menu.component = params.get("component")
                menu.is_visible = params.get("is_visible")
                menu.is_cache = params.get("is_cache")
                menu.is_leaf = params.get("is_leaf")
                menu.system_id = params.get("system_id")
                menu.short_name = params.get("short_name")
                menu.remark = params.get("remark")
                menu.status = params.get("status")
                menu.update_time = datetime.datetime.now()
                session.commit()
                return Response(Result(data=1))
        except Exception as e:
            print("更新菜单异常：",e)
            if session:
               session.rollback()
            return Response(Result(code=444, msg="更新失败！", data=0))
        finally:
            if  session:
                session.close()


'''菜单新增'''
class MenuAdd(APIView):
    def post(self, request):
        print("=========== 进入到了MenuAdd ==========")
        #请求参数
        params = request.data
        print("请求参数：", params)
        #菜单，组装成对象
        menu = Menu(
            parent_id=params.get("parent_id"),
            menu_name=params.get("menu_name"),
            path=params.get("path"),
            icon=params.get("icon"),
            sort=params.get("sort"),
            permission=params.get("permission"),
            menu_type=params.get("menu_type"),
            component=params.get("component"),
            is_visible=params.get("is_visible"),
            is_cache=params.get("is_cache"),
            is_leaf=params.get("is_leaf"),
            system_id=params.get("system_id"),
            short_name=params.get("short_name"),
            remark=params.get("remark"),
            status=params.get("status"),
            update_date=datetime.datetime.now(),
            create_date=datetime.datetime.now()

        )
        try:
            MySqlDb.insert_by_model(menu)
            return Response(Result(data=1))
        except Exception as e:
            print("新增菜单异常：",e)
            return Response(Result(code=444, msg="新增失败！", data=0))


'''删除菜单'''
class MenuDelete(APIView):
    #get请求
    def get(self, request):
        print("=========== 进入到了MenuDelete ==========")
        #请求参数
        params = request.GET.dict()
        print("请求参数：", params)
        #删除菜单
        try:
            #删除菜单
            sql = "delete from sys_menu where id=:id"
            count = MySqlDb.delete(sql,params=params)
            if count==0:
                return Response(Result(code=444, msg="删除失败！", data=0))
            if count>0:
                return Response(Result(data=1))
        except Exception as e:
            print("删除菜单异常：",e)
            return Response(Result(code=444, msg="删除失败！", data=0))

'''
#用户菜单树:
 前置条件-登录之后，根据用户角色查询出菜单树
    1.超级管理员，可以查询所有菜单
    2.普通用户，只能查询自己的菜单
    3.角色管理员，只能查询自己的菜单
'''
class UserMenuTree(APIView):
    def get(self, request):
        print("=========== 进入到了UserMenuTree ==========")
        # 获取请求参数
        params = request.GET.dict()
        print("params:",params)
        #取出用户会话信息

        user:User = request.session.get("user_info")
        username = user.get("username")
        '''超级管理员，可以查询所有菜单（特殊处理）'''
        if username == 'admin':
            all_menu_tree = get_all_menu_tree()
            return Response(Result(data=all_menu_tree))

        user_id = None
        if user:
            user_id = user.get("id")
        else:
            user_id = params.get("user_id")

        #查询出菜单表数据
        sql = "select * from sys_menu where status=1"
        menu_list = MySqlDb.query(sql)
        #转换成字典
        menu_dict = {}
        for item in menu_list:
            menu_dict[item["id"]] = item

        #查询菜单树
        sql = '''  select
                    distinct t3.*
                    from
                        sys_user_role t1
                    left join sys_role_permission t2 on
                        t1.role_id = t2.role_id
                    left join sys_menu t3 on
                        t2.menu_id = t3.id
                    where t1.user_id = :user_id
	          '''
        params = {
            "user_id":user_id
        }
        #查询出叶子授权树
        menu_leaf_list = MySqlDb.query(sql,params)
        #根据查询出来的叶子授权树，组装成菜单树
        temp_dict={}
        #组装菜单树
        for item in menu_leaf_list:
            #如果父菜单ID为0，说明是根菜单
            iterate_menu_tree(item,menu_dict,temp_dict)
        print("筛选父子级关系后的数据：", temp_dict)
        my_menu_tree = []
        for key,item in temp_dict.items():
            #如果父菜单ID为0，说明是根菜单
             if item.get("parent_id") == 0:
                 my_menu_tree.append(item)
                 print("key:",key)
        return Response(Result(data=my_menu_tree))

def iterate_menu_tree(node,menu_dict,temp_dict):
    parent_id = node["parent_id"]
    if parent_id == 0:
        #说明是根菜单
        top_parent = temp_dict.get(node["id"])
        if not top_parent:
            temp_dict[node["id"]] = {
                "id":node["id"],
                "parent_id":0,
                "title":node["menu_name"],
                "icon": node["icon"],
                "url": node.get("path"),
                "children":[]
            }
        else:
            #补充顶级的parent_id，后续筛选需要
            top_parent["parent_id"] = 0
        return
    else:
        parent_node = menu_dict[parent_id]
        temp_parent_node = temp_dict.get(parent_id)
        #创建级组装的父节点
        if not temp_parent_node:
            temp_parent_node = {
                "id":parent_node["id"],
                "title":parent_node["menu_name"],
                "icon": parent_node["icon"],
                "url": parent_node.get("path"),
                "children":[]
            }
            temp_dict[parent_id] = temp_parent_node
        # 当前节点不是叶子

        if  node["is_leaf"] != 1:
            #temp_menu_dict是否存在当前节点
            if not temp_dict.get(node["id"]):
                temp_dict[node["id"]] = {
                    "id":node["id"],
                    "title":node["menu_name"],
                    "icon": node["icon"],
                    "url": node.get("path"),
                    "children":[]
                }
            #把当前节点添加到父节点的children列表中(注意去重)
            if not temp_dict[node["id"]] in temp_parent_node["children"]:
                temp_parent_node["children"].append(temp_dict[node["id"]])
        #不是顶级路子叶子节点，继续遍历
        iterate_menu_tree(parent_node,menu_dict,temp_dict)

'''查询超级管理菜单树（所有）'''
def get_all_menu_tree():
    # 根据系统ID查询菜单列表
    sql = "select id,menu_name,parent_id,icon,path from sys_menu sm where sm.status=1 and is_leaf != 1 order by sort asc"
    list = MySqlDb.query(sql)
    # 散列成字典
    menu_dict = {}
    for item in list:
        menu_dict[item["id"]] = item
    # 组装树形结构
    menu_tree = []
    for item in list:
        item["title"] = item["menu_name"]
        item["icon"] = item["icon"]
        item["url"] = item.get("path")
        # 如果父菜单ID为0，说明是根菜单
        if item["parent_id"] == 0:
            menu_tree.append(item)
        else:
            # 如果父菜单ID不为0，说明是子菜单
            parent_menu = menu_dict[item["parent_id"]]
            # 子菜单不存在时，创建一个空列表
            if "children" not in parent_menu:
                parent_menu["children"] = []
            # 把子菜单添加到父菜单的children列表中
            parent_menu["children"].append(item)
    return menu_tree


